#include "simplificadores.h"
#include "AB.h"
#include "literal.h"
#include "expresion.h"
#include <stdio.h>
#include <stdlib.h>

int calcular(const TAB* origen, TAB* destino){
  int error,numI,numD,MAerror;
  TLiteral litI,litD,lit;
  char *string;
  TPila pila;
  TAB ramaIzq,ramaDer,calcDer,calcIzq;
  float num;

  AB_Crear(destino,sizeof(TLiteral));

  AB_MoverCte(origen,RAIZ,&error);
  AB_ElemCte(*origen,&lit);
  if(!Literal_EsOperador(&lit)){
    AB_Insertar(destino,RAIZ,&lit,&error);
    Literal_Destruir(&lit);
    return 1;
  }

  Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
  Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
  calcular(&ramaDer,&calcDer);
  calcular(&ramaIzq,&calcIzq);

  AB_ElemCte(calcDer,&litD);
  Literal_AString(&litD,&string);
  numD=atoi(string);
  AB_ElemCte(calcIzq,&litI);
  free(string);
  Literal_AString(&litI,&string);
  numI=atoi(string);
  free(string);

  AB_ElemCte(*origen,&lit);
  Literal_AString(&lit,&string);

  MAerror=1;

  switch (string[0]){
    case '+':
      num=numI+numD;
    break;

    case '-':
      num=numI-numD;
    break;

    case '*':
      num=numI*numD;
    break;

    case '/':
      if(numD==0)
        MAerror= -3;
      else{
        num=numI/numD;
      }
    break;
  }

  if(MAerror==1){
    P_Crear(&pila,sizeof(TLiteral));
    string=(char*)realloc(string,sizeof(char)*100);
    if (num<0)
      sprintf(string,"(%f)",num);
    else
      sprintf(string,"%f",num);
    infijo_a_sufijo(string,"",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
  }


  free(string);
  Literal_Destruir(&lit);
  Literal_Destruir(&litD);
  Literal_Destruir(&litI);
  AB_Vaciar(&ramaIzq);
  AB_Vaciar(&ramaDer);
  AB_Vaciar(&calcIzq);
  AB_Vaciar(&calcDer);

  if(!P_Vacia(pila)) P_Vaciar(&pila);

  return MAerror;
}


/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado*/
int SimplificarConstante(const TAB* origen, TAB* destino) {
  TLiteral literal;
  int error;
  AB_ElemCte(*origen,&literal);
  AB_Crear(destino,sizeof(TLiteral));
  AB_Insertar(destino,RAIZ,&literal,&error);
  if (error) return -1;
  return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado*/
int SimplificarVariable(const TAB* origen, TAB* destino) {
  TLiteral literal;
  int error;
  AB_ElemCte(*origen,&literal);
  AB_Crear(destino,sizeof(TLiteral));
  AB_Insertar(destino,RAIZ,&literal,&error);
  if (error) return -1;
  return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarSuma(const TAB* origen, TAB* destino) {

TLiteral lit,litI,litD;
TExpresion ramaIzq,ramaDer,simpIzq,simpDer;
int error,ok;
char* der,*izq;
TPila pila;

Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
error=Expresion_Simplificar (&ramaIzq, &simpIzq);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
  return error;
}
error=Expresion_Simplificar (&ramaDer, &simpDer);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
  if(!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
  return error;
}

/*saco el contenido de los literales para saber si son =0*/
AB_MoverCte(&simpIzq,RAIZ,&error);
AB_ElemCte(simpIzq,&litI);
AB_MoverCte(&simpDer,RAIZ,&error);
AB_ElemCte(simpDer,&litD);

ok = Literal_AString(&litI, &izq);
if (!ok) return 0;
ok = Literal_AString(&litD, &der);
if (!ok) return 0;
error=0;

if (strcmp(izq,"0") && strcmp(der,"0") ){//si der e izq son distintas a 0
    AB_MoverCte(origen,RAIZ,&error);//voy al padre (+)
    AB_ElemCte(*origen,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    if (!error){
        AB_PegarSubarbol( &simpIzq,  destino, IZQ);
        AB_MoverCte(destino,RAIZ,&error);
        AB_PegarSubarbol( &simpDer,  destino, DER);
    }
}
else if (strcmp(izq,"0")){//si la rama izq es distinta de 0
    Expresion_Copiar_SubExpresion(&simpIzq,destino,RAIZ);
    }
else if (strcmp(der,"0")){//si la rama der es distinta de 0
    Expresion_Copiar_SubExpresion(&simpDer,destino,RAIZ);
    }
else{//las 2 ramas son 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    }
  free(izq);
  free(der);
  Expresion_Destruir(&ramaDer);
  Expresion_Destruir(&ramaIzq);
  Expresion_Destruir(&simpDer);
  Expresion_Destruir(&simpIzq);

if (!error) return 1;
else return 0;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarResta(const TAB* origen, TAB* destino) {

TLiteral lit,litI,litD;
TExpresion ramaIzq,ramaDer,simpIzq,simpDer;
int error,ok;
char* der,*izq;
TPila pila;

Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
error=Expresion_Simplificar(&ramaDer,&simpDer);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
  return error;
}
error=Expresion_Simplificar(&ramaIzq,&simpIzq);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
  if(!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
  return error;
}

/*saco el contenido de los literales para saber si son =0*/
AB_MoverCte(&simpIzq,RAIZ,&error);
AB_ElemCte(simpIzq,&litI);
AB_MoverCte(&simpDer,RAIZ,&error);
AB_ElemCte(simpDer,&litD);

ok = Literal_AString(&litI, &izq);
if (!ok) return 0;
ok = Literal_AString(&litD, &der);
if (!ok) return 0;
error=0;

if (strcmp(izq,"0") && strcmp(der,"0") ){//si der e izq son distintas a 0
    AB_Crear(destino,sizeof(TLiteral));//FALTO ESTA LINEA Cesar
    AB_MoverCte(origen,RAIZ,&error);//voy ala raiz (-)
    AB_ElemCte(*origen,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    AB_PegarSubarbol( &simpIzq,  destino, IZQ);
    AB_MoverCte(destino,RAIZ,&error);
    AB_PegarSubarbol( &simpDer,  destino, DER);
}
else if (strcmp(izq,"0")){//si la rama izq es distinta de 0
    Expresion_Copiar_SubExpresion(&simpIzq,destino,RAIZ);
    }
else if (strcmp(der,"0")){//si la rama der es distinta de 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("*","",&pila);
    P_Sacar(&pila,&lit);//saco -1
    AB_Insertar(destino,RAIZ,&lit,&error);
    infijo_a_sufijo("(-1)","",&pila);
    P_Sacar(&pila,&lit);//saco *
    AB_Insertar(destino,IZQ,&lit,&error);
    AB_MoverCte(destino,RAIZ,&error);//voy ala raiz (*)
//    Expresion_Copiar_SubExpresion(&simpDer,  destino, DER,"x");
    AB_PegarSubarbol(&simpDer,  destino, DER);

    }
else{//las 2 ramas son 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    }

  free(izq);
  free(der);
  Expresion_Destruir(&ramaDer);
  Expresion_Destruir(&ramaIzq);
  Expresion_Destruir(&simpDer);
  Expresion_Destruir(&simpIzq);

if (!error) return 1;
else return 0;

}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarProducto(const TAB* origen, TAB* destino) {

  TLiteral literal;
  TExpresion ramaIzq,ramaDer,simpIzq,simpDer;
  int error;
  char* el_literal;
  TPila pila;

  Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
  Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
  error=Expresion_Simplificar(&ramaDer,&simpDer);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
  return error;
}
  error=Expresion_Simplificar(&ramaIzq,&simpIzq);
if(error!=1){
  if(!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
  if(!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
  if(!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
  if(!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
  return error;
}

  AB_MoverCte(&simpIzq,RAIZ,&error);
  AB_ElemCte(simpIzq,&literal);
  Literal_AString(&literal,&el_literal);
  Literal_Destruir(&literal);
  if (!strcmp(el_literal,"0")){
    AB_Crear(destino,sizeof(TLiteral));
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    Literal_Destruir(&literal);
    free(el_literal);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpIzq);
    return 1;
  }
  if (!strcmp(el_literal,"1")){
    AB_MoverCte(&simpDer,RAIZ,&error);
    if (error) return -1;
    AB_Crear(destino,sizeof(TLiteral));
    Expresion_Copiar_SubExpresion(&simpDer,destino,RAIZ);
    free(el_literal);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpIzq);
    return 1;
  }
  AB_MoverCte(&simpDer,RAIZ,&error);
  AB_ElemCte(simpDer,&literal);
  free(el_literal);
  Literal_AString(&literal,&el_literal);
  if (!strcmp(el_literal,"0")){
    AB_Crear(destino,sizeof(TLiteral));
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    Literal_Destruir(&literal);
    free(el_literal);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpIzq);
    return 1;
  }
  if (!strcmp(el_literal,"1")){
    AB_MoverCte(&simpIzq,RAIZ,&error);
    if (error) return -1;
    AB_Crear(destino,sizeof(TLiteral));
    Expresion_Copiar_SubExpresion(&simpIzq,destino,RAIZ);
    free(el_literal);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpIzq);
    return 1;
  }

  AB_Crear(destino,sizeof(TLiteral));
  P_Crear(&pila,sizeof(TLiteral));
  infijo_a_sufijo("*","",&pila);
  P_Sacar(&pila,&literal);
  AB_Insertar(destino,RAIZ,&literal,&error);
  Literal_Destruir(&literal);
  AB_PegarSubarbol(&simpDer,destino,DER);
  AB_MoverCte(destino,RAIZ,&error);
  AB_PegarSubarbol(&simpIzq,destino,IZQ);
  free(el_literal);
  Expresion_Destruir(&ramaDer);
  Expresion_Destruir(&ramaIzq);
  Expresion_Destruir(&simpDer);
  Expresion_Destruir(&simpIzq);
  return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarDivision(const TAB* origen, TAB* destino) {
  TLiteral literal,literal2;
  TExpresion ramaIzq,ramaDer,simpIzq,simpDer;
  int error,se_cumple,mathE;
  char *el_literal,*el_literal2;
  TPila pila;

  mathE=0;

  Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
  Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
  error=Expresion_Simplificar(&ramaIzq,&simpIzq);
  if(error!=1) return error;
  error=Expresion_Simplificar(&ramaDer,&simpDer);
  if(error!=1) return error;

  AB_MoverCte(&simpIzq,RAIZ,&error);
  AB_MoverCte(&simpDer,RAIZ,&error);
  AB_ElemCte(simpIzq,&literal);
  AB_ElemCte(simpDer,&literal2);
  Literal_AString(&literal,&el_literal);
  Literal_AString(&literal2,&el_literal2);

  se_cumple=0;
  if(!Literal_EsOperador(&literal2)){   //el denominador es una funcion
    if (!strcmp(el_literal,el_literal2)){
      if(strcmp(el_literal,"0")){
        AB_Crear(destino,sizeof(TLiteral));
        P_Crear(&pila,sizeof(TLiteral));
        infijo_a_sufijo("1","",&pila);
        P_Sacar(&pila,&literal);
        AB_Insertar(destino,RAIZ,&literal,&error);
        se_cumple=1;
      }
    }
    if(!strcmp(el_literal2,"1")){//denominador igual a 1
      AB_Crear(destino,sizeof(TLiteral));
      AB_MoverCte(&simpIzq,RAIZ,&error);
      Expresion_Copiar_SubExpresion(&simpIzq,destino,RAIZ);
      se_cumple=1;
    }
    else if (!strcmp(el_literal2,"0")){//denominador igual a 0
    se_cumple=1;
    mathE=-3;
    }
  }

  if( (!strcmp(el_literal,"0")) && (strcmp(el_literal2,"0")) ){
        AB_Crear(destino,sizeof(TLiteral));
        P_Crear(&pila,sizeof(TLiteral));
        infijo_a_sufijo("0","",&pila);
        P_Sacar(&pila,&literal);
        AB_Insertar(destino,RAIZ,&literal,&error);
        se_cumple=1;
  }

  if (!se_cumple){
    AB_Crear(destino,sizeof(TLiteral));
    AB_MoverCte(origen,RAIZ,&error);
    AB_MoverCte(&simpIzq,RAIZ,&error);
    AB_MoverCte(&simpDer,RAIZ,&error);
    AB_ElemCte(*origen,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    AB_PegarSubarbol(&simpDer,destino,DER);
    AB_MoverCte(destino,RAIZ,&error);
    AB_PegarSubarbol(&simpIzq,destino,IZQ);
  }

  free(el_literal);
  free(el_literal2);
  Expresion_Destruir(&ramaDer);
  Expresion_Destruir(&ramaIzq);
  Expresion_Destruir(&simpDer);
  Expresion_Destruir(&simpIzq);
  if (!mathE) return 1;
  else return mathE;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarPotencia(const TAB* origen, TAB* destino) {

TLiteral literal;
TExpresion ramaIzq,ramaDer,simpIzq,simpDer,simpDer2;
int error,num;
char* litI,*litD;
TPila pila;


Expresion_Copiar_SubExpresion(origen,&ramaIzq,IZQ);
Expresion_Copiar_SubExpresion(origen,&ramaDer,DER);
error=Expresion_Simplificar(&ramaIzq,&simpIzq);
  if(error!=1){
    if (!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
    if (!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
    if (!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
    return error;
  }
error=Expresion_Simplificar(&ramaDer,&simpDer2);
  if(error!=1){
    if (!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
    if (!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
    if (!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
    if (!AB_Vacio(simpDer2)) AB_Vaciar(&simpDer2);
    return error;
  }

error=calcular(&simpDer2,&simpDer);
  if(error!=1){
    if (!AB_Vacio(ramaIzq)) AB_Vaciar(&ramaIzq);
    if (!AB_Vacio(ramaDer)) AB_Vaciar(&ramaDer);
    if (!AB_Vacio(simpIzq)) AB_Vaciar(&simpIzq);
    if (!AB_Vacio(simpDer2)) AB_Vaciar(&simpDer2);
    if (!AB_Vacio(simpDer)) AB_Vaciar(&simpDer);
    return error;
  }

AB_MoverCte(&simpIzq,RAIZ,&error);
AB_ElemCte(simpIzq,&literal);
Literal_AString(&literal,&litI);
Literal_Destruir(&literal);

AB_MoverCte(&simpDer,RAIZ,&error);
AB_ElemCte(simpDer,&literal);
Literal_AString(&literal,&litD);
Literal_Destruir(&literal);

num=atoi(litD);

if ((strcmp(litI,"0")!=0) && (strcmp(litD,"0")==0)){//si el exponente es 0 y la base no es 0
    AB_Crear(destino,sizeof(TLiteral));
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("1","",&pila);
    P_Sacar(&pila,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    Literal_Destruir(&literal);
    free(litD);
    free(litI);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpDer2);
    Expresion_Destruir(&simpIzq);
    }
else if ((strcmp(litI,"0")==0) && (strcmp(litD,"0")!=0) && (num>0)){
//else if ((strcmp(litI,"0")==0) && (strcmp(litD,"0")!=0) && (strcmp(litD,"-1")!=0)){
    //si la base es 0 y el exponente no es 0 y no es -1
    AB_Crear(destino,sizeof(TLiteral));
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    Literal_Destruir(&literal);
    free(litD);
    free(litI);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpDer2);
    Expresion_Destruir(&simpIzq);
    }
else if ((strcmp(litI,"0")==0) && ((strcmp(litD,"0")==0) || (num<0))){
//else if ((strcmp(litI,"0")==0) && ((strcmp(litD,"0")==0) || (strcmp(litD,"-1")==0))){
    //caso de error matematico (0^0) o (0^-1)
    free(litI);
    free(litD);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpDer2);
    Expresion_Destruir(&simpIzq);
    return -3;
}
else if(strcmp(litD,"1")==0){//si el exponenete es 1
    AB_MoverCte(&simpIzq,RAIZ,&error);
    AB_Crear(destino,sizeof(TLiteral));
    Expresion_Copiar_SubExpresion(&simpIzq,destino,RAIZ);
    free(litI);
    free(litD);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpDer2);
    Expresion_Destruir(&simpIzq);
    }
else if (strcmp(litI,"0")!=0 && strcmp(litD,"0")!=0 && strcmp(litD,"1")){
    //en caso de que el exponente no sea 0 o 1 y que la base no sea 0
    //Expresion_Copiar_SubExpresion(origen,destino,RAIZ);

    AB_Crear(destino,sizeof(TLiteral));
    AB_MoverCte(&simpIzq,RAIZ,&error);
    AB_MoverCte(&simpDer,RAIZ,&error);

    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("^","",&pila);
    P_Sacar(&pila,&literal);
    AB_Insertar(destino,RAIZ,&literal,&error);
    Literal_Destruir(&literal);

    AB_PegarSubarbol(&simpIzq,destino,IZQ);//pego la base
    AB_MoverCte(destino,RAIZ,&error);//muevo a ^
    AB_PegarSubarbol(&simpDer,destino,DER);//pego la el exponente
    AB_MoverCte(destino,RAIZ,&error);//muevo a la raiz ^

    free(litD);
    free(litI);
    Expresion_Destruir(&ramaDer);
    Expresion_Destruir(&ramaIzq);
    Expresion_Destruir(&simpDer);
    Expresion_Destruir(&simpDer2);
    Expresion_Destruir(&simpIzq);
    }
return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarSeno(const TAB* origen, TAB* destino) {

TLiteral lit;
TExpresion rama,simp;
int error,ok;
char* expr;
TPila pila;

Expresion_Copiar_SubExpresion(origen,&rama,DER);
error=Expresion_Simplificar (&rama, &simp);
if(error!=1){
  if(!AB_Vacio(rama)) AB_Vaciar(&rama);
  if(!AB_Vacio(simp)) AB_Vaciar(&simp);
  return error;
}


AB_MoverCte(&simp,RAIZ,&error);
AB_ElemCte(simp,&lit);

ok = Literal_AString(&lit, &expr);
if (!ok) return 0;

if (strcmp(expr,"0")){//si es distinto de 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    AB_MoverCte(origen,RAIZ,&error);//voy al padre (sen)
    AB_ElemCte(*origen,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    AB_PegarSubarbol(&simp,destino,DER);
    }
else{//si es igual a 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    }
  free(expr);
  Expresion_Destruir(&rama);
  Expresion_Destruir(&simp);

return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarCoseno(const TAB* origen, TAB* destino) {

TLiteral lit;
TExpresion rama,simp;
int error,ok;
char* expr;
TPila pila;

Expresion_Copiar_SubExpresion(origen,&rama,DER);
error=Expresion_Simplificar (&rama, &simp);
if(error!=1){
  if(!AB_Vacio(rama)) AB_Vaciar(&rama);
  if(!AB_Vacio(simp)) AB_Vaciar(&simp);
  return error;
}


AB_MoverCte(&simp,RAIZ,&error);
AB_ElemCte(simp,&lit);

ok = Literal_AString(&lit, &expr);
if (!ok) return 0;

if (strcmp(expr,"0")){//si es distinto de 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    AB_MoverCte(origen,RAIZ,&error);//voy al padre (sen)
    Expresion_Copiar_SubExpresion(origen,destino,RAIZ);
    }
else{//si es igual a 0
    AB_Crear(destino,sizeof(TLiteral));//********NO SE si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("1","",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    }

  free(expr);
  Expresion_Destruir(&rama);
  Expresion_Destruir(&simp);
return 1;
}

/*PRE: Recibe un arbol origen creado y no vacio y otro arbol destino no creado.
  POS: Devuelve el arbol origen simplificado en el arbol destino.
  Devuelve: 1 si termina sin errores.
           -1 si ocurre algun error inesperado
           -3 si encuentra alguna funcion matematica no valida.*/
int SimplificarLogaritmo(const TAB* origen, TAB* destino) {

TLiteral lit;
TExpresion rama,simp;
int error,ok;
char* expr;
TPila pila;

Expresion_Copiar_SubExpresion(origen,&rama,DER);
error=Expresion_Simplificar (&rama, &simp);
if(error!=1){
  if(!AB_Vacio(rama)) AB_Vaciar(&rama);
  if(!AB_Vacio(simp)) AB_Vaciar(&simp);
  return error;
}

AB_MoverCte(&simp,RAIZ,&error);
AB_ElemCte(simp,&lit);

ok = Literal_AString(&lit, &expr);
if (!ok) return 0;

if (strcmp(expr,"1")){//si es distinto de 0
    AB_Crear(destino,sizeof(TLiteral));//********no se si es necesaria********
    AB_MoverCte(origen,RAIZ,&error);//voy al padre (sen)
    AB_ElemCte(*origen,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    AB_PegarSubarbol(&simp,destino,DER);
    }
else{//si es igual a 0
    AB_Crear(destino,sizeof(TLiteral));//********NO SE si es necesaria********
    P_Crear(&pila,sizeof(TLiteral));
    infijo_a_sufijo("0","",&pila);
    P_Sacar(&pila,&lit);
    AB_Insertar(destino,RAIZ,&lit,&error);
    }
  free(expr);
  Expresion_Destruir(&rama);
  Expresion_Destruir(&simp);
return 1;
}

